﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DACU.Properties;
using DACU.Tools;
using Un4seen.Bass;

namespace DACU.Player
{
	class BassException:Exception
	{
		private readonly int _errorCode;
		public int ErrorCode
		{
			get { return _errorCode; }
		}

		private readonly BASSError _bassError;
		public BASSError BassError
		{
			get { return _bassError; }
		}

		private readonly string _description;
		public string Description
		{
			get { return _description; }
		}

		public BassException(int errorCode)
		{
			_errorCode = errorCode;
			_bassError = (BASSError) errorCode;
			_description = CodeToMessage(BassError);
		}

		public BassException(BASSError errorCode)
		{
			_errorCode = (int)errorCode;
			_bassError = errorCode;
			_description = CodeToMessage(BassError);
		}

		static string CodeToMessage(BASSError errorCode)
		{
			switch (errorCode)
			{
				case BASSError.BASS_ERROR_MEM:
					return Resources.BassException_BASS_ERROR_MEM;
				case BASSError.BASS_ERROR_FILEOPEN:
					return Resources.BassException_BASS_ERROR_FILEOPEN;
				case BASSError.BASS_ERROR_DRIVER:
					return Resources.BassException_BASS_ERROR_DRIVER;
				case BASSError.BASS_ERROR_BUFLOST:
					return Resources.BassException_BASS_ERROR_BUFLOST;
				case BASSError.BASS_ERROR_HANDLE:
					return Resources.BassException_BASS_ERROR_HANDLE;
				case BASSError.BASS_ERROR_FORMAT:
					return Resources.BassException_BASS_ERROR_FORMAT;
				case BASSError.BASS_ERROR_POSITION:
					return "Invalid playback position";
				case BASSError.BASS_ERROR_INIT:
					return "BASS_Init has not been successfully called";
				case BASSError.BASS_ERROR_START:
					return "BASS_Start has not been successfully called";
				case BASSError.BASS_ERROR_NOCD:
					return "No CD in drive";
				case BASSError.BASS_ERROR_CDTRACK:
					return "Invalid track number";
				case BASSError.BASS_ERROR_ALREADY:
					return "Already initialized/paused/whatever";
				case BASSError.BASS_ERROR_NOPAUSE:
					return "Not paused";
				case BASSError.BASS_ERROR_NOTAUDIO:
					return "Not an audio track";
				case BASSError.BASS_ERROR_NOCHAN:
					return "Can't get a free channel";
				case BASSError.BASS_ERROR_ILLTYPE:
					return "An illegal type was specified";
				case BASSError.BASS_ERROR_ILLPARAM:
					return "An illegal parameter was specified";
				case BASSError.BASS_ERROR_NO3D:
					return "No 3D support";
				case BASSError.BASS_ERROR_NOEAX:
					return "No EAX support";
				case BASSError.BASS_ERROR_DEVICE:
					return "Illegal device number";
				case BASSError.BASS_ERROR_NOPLAY:
					return "Not playing";
				case BASSError.BASS_ERROR_FREQ:
					return "Illegal sample rate";
				case BASSError.BASS_ERROR_NOTFILE:
					return "The stream is not a file stream";
				case BASSError.BASS_ERROR_NOHW:
					return "No hardware voices available";
				case BASSError.BASS_ERROR_EMPTY:
					return "The MOD music has no sequence data";
				case BASSError.BASS_ERROR_NONET:
					return "No internet connection could be opened";
				case BASSError.BASS_ERROR_CREATE:
					return "Couldn't create the file";
				case BASSError.BASS_ERROR_NOFX:
					return "Effects are not available";
				case BASSError.BASS_ERROR_PLAYING:
					return "The channel is playing";
				case BASSError.BASS_ERROR_NOTAVAIL:
					return "Requested data is not available";
				case BASSError.BASS_ERROR_DECODE:
					return "The channel is a 'decoding channel'";
				case BASSError.BASS_ERROR_DX:
					return "A sufficient DirectX version is not installed";
				case BASSError.BASS_ERROR_TIMEOUT:
					return "Connection timedout";
				case BASSError.BASS_ERROR_FILEFORM:
					return "Unsupported file format";
				case BASSError.BASS_ERROR_SPEAKER:
					return "Unavailable speaker";
				case BASSError.BASS_ERROR_VERSION:
					return "Invalid BASS version (used by add-ons)";
				case BASSError.BASS_ERROR_CODEC:
					return "Codec is not available/supported";
				case BASSError.BASS_ERROR_ENDED:
					return "The channel/file has ended";
				case BASSError.BASS_ERROR_BUSY:
					return "The device is busy (eg. in 'exclusive' use by another process)";
				case BASSError.BASS_ERROR_UNKNOWN:
					return "Some other mystery error";
				case BASSError.BASS_ERROR_WMA_LICENSE:
					return "BassWma: the file is protected";
				case BASSError.BASS_ERROR_WMA_WM9:
					return "BassWma: WM9 is required";
				case BASSError.BASS_ERROR_WMA_DENIED:
					return "BassWma: access denied (user/pass is invalid)";
				case BASSError.BASS_ERROR_WMA_CODEC:
					return "BassWma: no appropriate codec is installed";
				case BASSError.BASS_ERROR_WMA_INDIVIDUAL:
					return "BassWma: individualization is needed";
				case BASSError.BASS_ERROR_ACM_CANCEL:
					return "BassEnc: ACM codec selection cancelled";
				case BASSError.BASS_ERROR_CAST_DENIED:
					return "BassEnc: Access denied (invalid password)";
				case BASSError.BASS_VST_ERROR_NOINPUTS:
					return "BassVst: the given effect has no inputs and is probably a VST instrument and no effect";
				case BASSError.BASS_VST_ERROR_NOOUTPUTS:
					return "BassVst: the given effect has no outputs";
				case BASSError.BASS_VST_ERROR_NOREALTIME:
					return "BassVst: the given effect does not support realtime processing";
				case BASSError.BASS_FX_ERROR_NODECODE:
					return "BassFx: Not a decoding channel";
				case BASSError.BASS_FX_ERROR_BPMINUSE:
					return "BassFx: BPM detection is in use";
				case BASSError.BASS_ERROR_VIDEO_ABORT:
					return "BASSVIDEO: Action was abort";
				case BASSError.BASS_ERROR_VIDEO_CANNOT_CONNECT:
					return "BASSVIDEO: Cannot connect filter / pin.";
				case BASSError.BASS_ERROR_VIDEO_CANNOT_READ:
					return "BASSVIDEO: Cannot read file.";
				case BASSError.BASS_ERROR_VIDEO_CANNOT_WRITE:
					return "BASSVIDEO: Cannot write file.";
				case BASSError.BASS_ERROR_VIDEO_FAILURE:
					return "BASSVIDEO: Failure to do.";
				case BASSError.BASS_ERROR_VIDEO_FILTER:
					return "BASSVIDEO: Error cause by filter.";
				case BASSError.BASS_ERROR_VIDEO_INVALID_CHAN:
					return "BASSVIDEO: Invalid BassVideo channel.";
				case BASSError.BASS_ERROR_VIDEO_INVALID_DLL:
					return "BASSVIDEO: Wrong dll.";
				case BASSError.BASS_ERROR_VIDEO_INVALID_FORMAT:
					return "BASSVIDEO: Invalid format.";
				case BASSError.BASS_ERROR_VIDEO_INVALID_HANDLE:
					return "BASSVIDEO: Invalid handle.";
				case BASSError.BASS_ERROR_VIDEO_INVALID_PARAMETER:
					return "BASSVIDEO: Invalid parameter.";
				case BASSError.BASS_ERROR_VIDEO_NO_AUDIO:
					return "BASSVIDEO: No sound.";
				case BASSError.BASS_ERROR_VIDEO_NO_EFFECT:
					return "BASSVIDEO: No 'Video Effect' detected.";
				case BASSError.BASS_ERROR_VIDEO_NO_INTERFACE:
					return "BASSVIDEO: Failed to querry interface.";
				case BASSError.BASS_ERROR_VIDEO_NO_RENDERER:
					return "BASSVIDEO: No renderer.";
				case BASSError.BASS_ERROR_VIDEO_NO_SUPPORT:
					return "BASSVIDEO: No support/Currently not supported.";
				case BASSError.BASS_ERROR_VIDEO_NO_VIDEO:
					return "BASSVIDEO: No Video.";
				case BASSError.BASS_ERROR_VIDEO_NOT_ALLOWED:
					return "BASSVIDEO: Not allowed.";
				case BASSError.BASS_ERROR_VIDEO_NOT_CONNECTED:
					return "BASSVIDEO: Filter/Pin had not connected.";
				case BASSError.BASS_ERROR_VIDEO_NOT_EXISTS:
					return "BASSVIDEO: Not existing object.";
				case BASSError.BASS_ERROR_VIDEO_NOT_FOUND:
					return "BASSVIDEO: Object not found";
				case BASSError.BASS_ERROR_VIDEO_NOT_READY:
					return "BASSVIDEO: Graph/Filter not ready.";
				case BASSError.BASS_ERROR_VIDEO_NULL_DEVICE:
					return "BASSVIDEO: Device is null.";
				case BASSError.BASS_ERROR_VIDEO_OPEN:
					return "BASSVIDEO: Cannot open.";
				case BASSError.BASS_ERROR_VIDEO_OUTOFMEMORY:
					return "BASSVIDEO: Not enough memory.";
				case BASSError.BASS_ERROR_VIDEO_PARTIAL_RENDER:
					return "BASSVIDEO: Stream is in an unsupported format.";
				case BASSError.BASS_ERROR_VIDEO_TIME_OUT:
					return "BASSVIDEO: A Timeout occured.";
				case BASSError.BASS_ERROR_VIDEO_UNKNOWN_FILE_TYPE:
					return "BASSVIDEO: Unknown file type.";
				case BASSError.BASS_ERROR_VIDEO_UNSUPPORT_STREAM:
					return "BASSVIDEO: Cannot play file, format not supported.";
				case BASSError.BASS_ERROR_VIDEO_VIDEO_FILTER:
					return "BASSVIDEO: Cannot create video filter.";
				case BASSError.BASS_ERROR_WASAPI:
					return "BASSWASAPI: no WASAPI available";
					//case BASSError.BASS_OK:
				default:
					return "Unknown Error";
			}
		}

		public override string ToString()
		{
			return "BassError: {0}\nDescription: {1}\n".FormatStr(BassError,Description) + base.ToString();
		}
	}
}
